import 'package:any_reader/public.dart';
import 'package:any_reader/view_model/reader_model.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;

class ReaderPageAgent {
  static List<Map<String, Object>> getPageOffsets(
      String content,
      double height,
      double width,
      double fontSize,
      double lineHeight,
      Color textColor,
      ReadMode painterType) {
    String testContent =
        "测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测测";
    String _text = " "; //正文缓存
    int max = 0; //一行最多的文字
    double wordWidth = 0.0; //平均文字宽度
    double wordWidth2 = 0.0; //平均文字宽度
    double mViewWidth = width;
    double mViewHeight = height;
//    print("mViewHeight $mViewHeight");
//    print("mViewWidth $mViewWidth");
//    print("maxWidth ${ScreenUtil().setWidth(750)}");
//    print("maxHeight ${ScreenUtil().setHeight(1334)}");
    //首先替换首行缩进
    _text += content
        .trimLeft()
        .replaceAll(RegExp(r"\s+"), "")
        .replaceAll(RegExp(r"<br>"), "\n ");
//    .replaceAll(RegExp("/\s+/"), "").replaceAll("\n", "\n ")
    //创建画板
    TextPainter textPainter = new TextPainter(
        strutStyle: StrutStyle(leading: 1),
        textDirection: TextDirection.ltr,
        locale: Locale('zh', 'CH'));
    //放入计算测试正文
    textPainter.text = TextSpan(
      text: testContent,
      style: TextStyle(
        fontSize: fontSize,
        height: lineHeight,
        locale: Locale('zh', 'CH'),
      ),
    );
    textPainter.layout(maxWidth: mViewWidth);
    //包含了所有行数
    List<ui.LineMetrics> list = textPainter.computeLineMetrics();
    max = calcMax(list, textPainter, testContent);
    wordWidth = mViewWidth / max;
//    print("max ${max.toString()}  wordWidth ${wordWidth.toString()}");
    //放入正文
    textPainter.text = TextSpan(
      text: _text,
      style: TextStyle(
        color: textColor,
        height: lineHeight,
        fontSize: fontSize,
        locale: Locale('zh', 'CH'),
        fontFamily: "dengxian",
      ),
    );
    textPainter.layout(maxWidth: mViewWidth);
    //得到真正的lineList
    list = textPainter.computeLineMetrics();
    double nowHeight = 0.0; //循环的高度
    List<Map<String, Object>> result = []; //返回的pageList
    //总页->页->行->字
    List<List<Map<String, dynamic>>> _tempPage = [];

//    double maxLineHeight = 0.0;
//    int maxLine = 0;
//    for (int i = 0; i < list.length; i++) {
//      if (maxLineHeight <= list[i].height) {
//        maxLineHeight = list[i].height;
//      }
//    }
//    maxLine = (mViewHeight / maxLineHeight).floor();

    for (int i = 0; i < list.length; i++) {
      ui.LineMetrics item = list[i];
      double lineHeight = item.height * i; //行高
      double lineEnd = item.width; //行宽
//      nowHeight += lineHeight;
      //获取该行
      TextPosition lineStart =
          textPainter.getPositionForOffset(Offset(lineEnd, lineHeight));
      //根据position获取该行的起始截至
      TextRange _ = textPainter.getLineBoundary(lineStart);
      //获取到该行的文字
      String line = _text.substring(_.start, _.end);
      //一行的list缓存
      List<Map<String, dynamic>> _temp = [];
      if (line.length > max / 1.1) {
        //如果这一行是满的，就重新计算子宽，否则按照预设字宽
        wordWidth2 = hasSpecChart(line, mViewWidth, wordWidth);
      }
      double left = 0.0;
      for (int index = 0; index < line.length; index++) {
        double _wordWidth = wordWidth; //处理特殊字符的宽度
        if (line.length > max / 1.1) {
          _wordWidth = calcWordWidth(line[index], _wordWidth, wordWidth2);
        }
        Offset offset;
        if (painterType == ReadMode.scroll) {
          offset = new Offset(left, lineHeight);
        } else {
          if (lineHeight + nowHeight > mViewHeight) {
            offset = new Offset(left, 0);
          } else {
            offset = new Offset(left, lineHeight + nowHeight);
          }
        }
        left += _wordWidth;
        var paragraphBuilder1 = ui.ParagraphBuilder(
          ui.ParagraphStyle(
            fontSize: fontSize,
            textAlign: TextAlign.justify,
            locale: Locale('zh', 'CH'),
            fontFamily: "dengxian",
            strutStyle: ui.StrutStyle(
              leading: 1,
            ),
          ),
        )
          ..pushStyle(ui.TextStyle(
            color: textColor,
          ))
          ..addText(line[index]);
        var paragraph1 = paragraphBuilder1.build()
          ..layout(ui.ParagraphConstraints(width: _wordWidth));
        _temp.add({"offset": offset, "paragraph": paragraph1});
      }
      //这里的lineHeight 改为了baseLine 获取的是从顶点到该行的高度，不再是这行文本的高度
      if (lineHeight + nowHeight < mViewHeight) {
        //这里的_temp为一行
        _tempPage.add(_temp);
      } else {
//        print(
//            "开新页了 ${result.length} lineHeight $lineHeight  nowHeight $nowHeight");
        //把上一页内容放入
        result.add({"page": _tempPage, "pageHeight": lineHeight + nowHeight});
        //清空
        _tempPage = [];
        nowHeight = -lineHeight;
        //开始放入新页内容
        _tempPage.add(_temp);
      }
      if (i == list.length - 1) {
        result.add({"page": _tempPage, "pageHeight": lineHeight + nowHeight});
      }
    }
    return result;
  }

  static double calcWordWidth(
      String char, double wordWidth, double wordWidth2) {
    RegExp spc = new RegExp(r"\.|，|,|“|”|。");
    Iterable<Match> matches = spc.allMatches(char);
//    print("matches ${matches.length} $char");
    if (matches.length > 0) {
      if (char == ".") return wordWidth / 4;
      return wordWidth / 2;
    } else {
      return wordWidth2;
    }
  }

  static double hasSpecChart(String line, double width, double wordWidth) {
    double _wordWidth = wordWidth;
    double _width = width;
    RegExp spc = new RegExp(r"，|,|“|”|。");
    RegExp spc2 = new RegExp(r"\.");
    Iterable<Match> matches = spc.allMatches(line);
    Iterable<Match> matches2 = spc2.allMatches(line);
//    print("${matches.length} | $line");

    if (matches2.length > 0) {
      line = line.replaceAll(spc2, "");
      _width = _width - (matches2.length * _wordWidth / 4);
    }
    if (matches.length > 0) {
      line = line.replaceAll(spc, "");
      _width = _width - (matches.length * _wordWidth / 2);
    }
    _wordWidth = _width / line.length;
    return _wordWidth;
  }

  static int calcMax(list, textPainter, _text) {
    int max = 0;
    for (int i = 0; i < list.length; i++) {
      ui.LineMetrics item = list[i];
      double lineHeight = item.height;
      double lineEnd = item.width;

      TextPosition lineStart =
          textPainter.getPositionForOffset(Offset(lineEnd, lineHeight * i));
      var _ = textPainter.getLineBoundary(lineStart);
      String line = _text.substring(_.start, _.end);
      if (line.length > max) max = line.length;
    }
    return max;
  }
}
